package org.as4game.resource.buffer
{
	import flash.display3D.Context3D;
	import flash.display3D.IndexBuffer3D;
	
	import org.as4game.resource.manager.IResource;
	

	/**
	 * 顶点缓冲区
	 * <li> 如果构造函数中 dynmicMemory=false, 则数据加载到显卡后, 内存空间被释放, 并且无法再次被修改
	 */
	public class IndexBuffer implements IResource
	{
		private var _indexCount:uint;					// 顶点个数
		private var _mem_buffer:Vector.<uint>;			// 内存缓存
		private var _card_buffer:IndexBuffer3D;		// 显存缓存
		
		private var _mem_dirty:Boolean;				// 内存是否失效
		private var _mem_dynmic:Boolean;				// 内存是否是动态的, 可随时修改
		
		
		public function IndexBuffer(){
		}
		
		/**
		 * 建立缓冲区
		 * @param indexCount 索引个数
		 * @param dynmicMemory 动态缓存, 可后期修改顶点数据
		 * @param buf 外部设置数据
		 */
		public function create( indexCount:uint, dynmicMemory:Boolean=false, buf:Vector.<uint>=null ):void{
			dispose();
			
			_indexCount = indexCount;
			_mem_buffer = buf || new Vector.<uint>( indexCount );
			
			_mem_dirty = true;
			_mem_dynmic = dynmicMemory;
		}
		
		/**
		 * 索引个数
		 */
		public function get indexCount():uint{
			return _indexCount;
		}
		
		/**
		 * 是否动态内存
		 */
		public function get isDynmicMemory():Boolean{
			return _mem_dynmic;
		}
		
		/**
		 * 获取顶点缓存以做修改
		 */
		public function getMemoryBuffer( bSetChange:Boolean=true ):Vector.<uint>{
			
			// 已经传送到显卡, 无法再被修改
			if( !_mem_dynmic && _card_buffer ){
				throw new Error("非动态内存无法被修改");
			}
			
			if( bSetChange ) _mem_dirty = true;
			
			return _mem_buffer;
		}
		
		
		/**
		 * 获取显卡数据
		 */
		public function getCardBuffer( context3D:Context3D ):IndexBuffer3D{

			if( !_indexCount|| !_mem_buffer || !_mem_dirty ) return _card_buffer;
			
			if( _card_buffer ) _card_buffer.dispose();
			
			_card_buffer = context3D.createIndexBuffer( _indexCount );
			_card_buffer.uploadFromVector( _mem_buffer, 0, _indexCount );
			
			if( ! _mem_dynmic ) _mem_buffer = null;
			_mem_dirty = false;
			
			return _card_buffer;
		}
		
		/**
		 * @inheritDoc
		 */
		public function dispose():void{
			_indexCount = 0;
			_mem_buffer = null;
			if( _card_buffer ){ 
				_card_buffer.dispose();
				_card_buffer = null;
			}
		}
		
		/**
		 * @inheritDoc
		 */
		public function get totalMemory():uint{
			return _indexCount * 4;
		}
	}
}